﻿using System;
using System.Linq;
using System.Security.Permissions;
using OS.Infrastructure.Domain;
using OS.Infrastructure.Domain.UnitOfWork;
using TaskKernel.Configuration;
using TaskKernel.Domain;
using TaskKernel.Domain.Interface;

namespace TaskWebApplicationUI.PresenterLayer
{
    public class AdminPermissionsPresenter : AbstractPresenter<IAdminPermissionsView>
    {
        private readonly IQueryAccount _queryAccount;
        private readonly IQueryDepartment _queryDepartment;
        private readonly IUnitOfWorkFactory _unitOfWork;
        private readonly ICommandRepository<Department> _command;

        public AdminPermissionsPresenter(IQueryDepartment queryDepartment, IQueryAccount queryAccount,
                                         IUnitOfWorkFactory unitOfWork, ICommandRepository<Department> command)
           
        {
            _queryDepartment = queryDepartment;
            _queryAccount = queryAccount;
            _unitOfWork = unitOfWork;
            _command = command;
        }

        public void OnViewInitialized()
        {
            using (var z = _unitOfWork.Create()){
                View.Accounts = _queryAccount.GetAllNotFiredAccounts().ToList();
            }
        }

        public void RefreshView()
        {
            using (var z = _unitOfWork.Create()){
                var changeDepartment = _queryDepartment.GetDepartment(View.DepartmentId);
                var userswithrole = changeDepartment.UsersWithRole.OrderBy(x => x.User.FullName).ToList();
                if (userswithrole.Any()) View.UsersWithRoles = userswithrole;
                View.DepartmentName = changeDepartment.DepartmentName;
            }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = TaskKernelConfiguration.AdminRole)]
        public void OnCreateDepartmentUser(string accountID, string role)
        {
            using (var z = _unitOfWork.Create())
            {
                var changeDepartment = _queryDepartment.GetDepartment(View.DepartmentId);
                var selectedRole = (RoleEnum)Enum.Parse(typeof(RoleEnum), role);
                var selectedAccount = _queryAccount.Get(new Guid(accountID));
                if (changeDepartment.CreateUserRole(selectedAccount, selectedRole))
                {
                    _command.Save(changeDepartment);
                    if (z.Commit())
                        View.Message = "Пользователь с ролью добавлен.";
                }
                else
                    View.Message = changeDepartment.Message;
                RefreshView();

            }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = TaskKernelConfiguration.AdminRole)]
        public void OnDeleteDepartmentUser(DepartmentUser user)
        {
            using (var z = _unitOfWork.Create())
            {
                var changeDepartment = _queryDepartment.GetDepartment(View.DepartmentId);
                var userWithRole = changeDepartment.UsersWithRole.SingleOrDefault(x => x.UID == user.UID);
                if (changeDepartment.DeleteUserRole(userWithRole))
                {
                    _command.Save(changeDepartment);
                    if (z.Commit())
                        View.Message = "Пользователь с ролью удален";
                }
                else
                    View.Message = changeDepartment.Message;
                RefreshView();
            }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = TaskKernelConfiguration.AdminRole)]
        public void OnUpdateDepartmentUser(DepartmentUser user)
        {
            using (var z = _unitOfWork.Create()){
                var changeDepartment = _queryDepartment.GetDepartment(View.DepartmentId);
                var userWithRole = changeDepartment.UsersWithRole.SingleOrDefault(x => x.UID == user.UID);
                if (changeDepartment.ChangeUserRole(userWithRole, user)){
                    _command.Save(changeDepartment);
                    if (z.Commit())
                    View.Message = "Роль изменена";
                }
                else
                    View.Message = changeDepartment.Message;
                RefreshView();
            }
        }
    }
}